// Haxzs Audio Server
// made by omghaxzs
// 2010

#include "http.h"

bool http::FindHeader(std::string header, HTTP_HEADER *out)
{
	// Look through the vector of headers
	for(int i = 0; i < headers.size(); i++)
	{
		// Do the headers equal each other?
		if (header == headers[i].header)
		{
			// Yes, return the header
			out = &headers[i];
			return true;
		}
	}

	// If not found, return false
	return false;
}

std::string http::Output()
{
	std::string output;

	// What type of message is it?
	switch(this->type)
	{
	case MESSAGE_TYPE::MESSAGE_REQUEST:
		{
			// Whats the method?
			switch(req.method)
			{
			case REQUEST_METHOD::METHOD_GET:
				{
					output.append("GET ");
					break;
				}
			case REQUEST_METHOD::METHOD_POST:
				{
					output.append("POST ");
					break;
				}
			}

			// Output the URI
			output.append(req.uri);
			output.append(" ");

			// What's the HTTP Version?
			switch(req.version)
			{
			case HTTP_VERSION::HTTP_VERSION_1_0:
				{
					output.append("HTTP/1.0");
					break;
				}
			case HTTP_VERSION::HTTP_VERSION_1_1:
				{
					output.append("HTTP/1.1");
					break;
				}
			}
			break;
		}
	case MESSAGE_TYPE::MESSAGE_RESPONSE:
		{
			// What's the HTTP Version?
			switch(resp.version)
			{
			case HTTP_VERSION::HTTP_VERSION_1_0:
				{
					output.append("HTTP/1.0 ");
					break;
				}
			case HTTP_VERSION::HTTP_VERSION_1_1:
				{
					output.append("HTTP/1.1 ");
					break;
				}
			}

			// Output the response code
			output.append(resp.code);
			break;
		}
	}

	// Newline it
	output.append("\r\n");

	// Now go through all the headers and output them
	for(int i = 0; i < this->headers.size(); i++)
	{
		// Header
		output.append(headers[i].header);

		// Separator
		output.append(": ");

		// Body
		output.append(headers[i].body);

		// Newline
		output.append("\r\n");
	}

	// Return it
	return output;
}

bool http::ParseHTTP(std::string http_data)
{
	try
	{
		// Okay, let's go through the data
		// Split it by newlines
		// Create a new vector of strings
		std::vector<std::string> newlines;

		while(http_data.find("\r\n") != std::string::npos)
		{
			std::string s;

			// Take the string out
			s = http_data.substr(0, http_data.find("\r\n"));

			// Put it in the newlines
			newlines.push_back(s);

			// Now delete that section
			http_data.erase(0, http_data.find("\r\n")+2);
		}

		// Now that we've sorted out all the newlines, let's go through each one
		for(int i = 0; i < newlines.size(); i++)
		{
			// The first newline should be the request, if not, then we're not doing anything else
			if (i == 0)
			{
				// Split it up with spaces
				std::vector<std::string> spaces;

				while(newlines[0].find(" ") != std::string::npos)
				{
					std::string s;

					// Take the string out
					s = newlines[0].substr(0, newlines[0].find(" "));

					// Put it in the spaces
					spaces.push_back(s);

					// Now delete that section
					newlines[0].erase(0, newlines[0].find(" ")+1);
				}

				// Add the rest into more spaces
				spaces.push_back(newlines[0]);

				// Now the first space should be either GET or POST, OR have HTTP in it
				if(spaces[0] == "GET")
				{
					req.method = REQUEST_METHOD::METHOD_GET;
					type = MESSAGE_TYPE::MESSAGE_REQUEST;
				}
				else if (spaces[0] == "POST")
				{
					req.method = REQUEST_METHOD::METHOD_POST;
					type = MESSAGE_TYPE::MESSAGE_REQUEST;
				}
				else
				{
					// Invalid HTTP Header
					return false;
				}

				// The next space is the URI
				req.uri = spaces[1];

				// The next space is the HTTP Version
				if(spaces[2] == "HTTP/1.1")
				{
					req.version = HTTP_VERSION::HTTP_VERSION_1_1;
				}
				else if (spaces[2] == "HTTP/1.0")
				{
					req.version = HTTP_VERSION::HTTP_VERSION_1_0;
				}
				else
				{
					// Invalid HTTP Header
					return false;
				}
			}
			else
			{
				if (newlines[i].length() > 0)
				{
					// Go through the rest and split them by colons
					std::vector<std::string> colons;

					while(newlines[i].find(":") != std::string::npos)
					{
						std::string s;

						// Take the string out
						s = newlines[i].substr(0, newlines[i].find(":"));

						// Put it in the spaces
						colons.push_back(s);

						// Now delete that section
						newlines[i].erase(0, newlines[i].find(":")+2);

						break;
					}

					// Now add the rest to the colons
					colons.push_back(newlines[i]);

					// Now add the colons vector to the headers
					HTTP_HEADER h;
					h.header = colons[0];
					h.body = colons[1];
					headers.push_back(h);
				}
			}
		}

		return true;
	}
	catch(std::exception e)
	{
		return false;
	}
}